package thema2project;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.*;
import javax.swing.border.*;
import java.awt.event.ActionEvent;
import java.util.*;

/**
 * A graphical view of the simulation grid. The view displays a colored
 * rectangle for each location representing its contents. It uses a default
 * background color. Colors for each type of species can be defined using the
 * setColor method.
 * 
 */
@SuppressWarnings({ "serial", "unused" })
public class SimulatorView extends JFrame implements ActionListener {
	// Colors used for empty locations.
	private static final Color EMPTY_COLOR = Color.green;

	// Color used for objects that have no defined color.
	private static final Color UNKNOWN_COLOR = Color.pink;

	private final String STEP_PREFIX = " Step: ";
	private final String POPULATION_PREFIX = " Population:  ";
	private JLabel stepLabel, population;
	private FieldView fieldView;
	private FieldStats fieldstats;

	private Simulator sim;
	private ActionListener OneActionListener;
	private ActionListener HonderdActionListener;
	private JButton eenstap;
	private JButton honderdstap;
	private JButton vijfHstap;
	private JButton reset;
	private JTextArea hList;
	private JTextArea columnTitles;
	private String lastHistory = "";
	private Renner renner;
	private int step;

	// A map for storing colors for participants in the simulation
	@SuppressWarnings("rawtypes")
	private Map<Class, Color> colors;

	public void actionPerformed(ActionEvent event) {
		if ((event.getActionCommand()).equals("1 step")) {
			if (renner == null || step == 100 || step == 500) {
				step = 1;
				renner = null;
				renner = new Renner(sim, step);
				new Thread(renner).start();
			} else {
				renner = null;
				renner = new Renner(sim, step);
				new Thread(renner).start();
			}
		}

		if ((event.getActionCommand()).equals("100 steps")) {
			if (renner == null || step == 1 || step == 500) {
				step = 100;
				renner = null;
				renner = new Renner(sim, step);
				new Thread(renner).start();
			} else {
				renner = null;
				renner = new Renner(sim, step);
				new Thread(renner).start();
			}
		}
		if ((event.getActionCommand()).equals("500 steps")) {
			if (renner == null || step == 1 || step == 100) {
				step = 500;
				renner = null;
				renner = new Renner(sim, step);
				new Thread(renner).start();
			} else {
				renner = null;
				renner = new Renner(sim, step);
				new Thread(renner).start();
			}
		}
		if ((event.getActionCommand()).equals("reset")) {
			sim.reset();
		}
	}

	/**
	 * Create a view of the given width and height.
	 * 
	 * @param height
	 *            The simulation's height.
	 * @param width
	 *            The simulation's width.
	 */
	@SuppressWarnings("rawtypes")
	public SimulatorView(Simulator sim) {
		this.sim = sim;
		fieldstats = new FieldStats();
		sim.setView(this);
		Container contentPane = getContentPane();
		makeMenuBar();

		setTitle("Foxes and rabbits simulation");

		JPanel panePanel = new JPanel();
		panePanel.setLayout(new FlowLayout());

		JLabel version = new JLabel("Version ");
		version.setBorder(BorderFactory.createLineBorder(Color.black));

		contentPane.add(createSimuScherm(), BorderLayout.CENTER);
		panePanel.add(createControllerPanel());
		contentPane.add(panePanel, BorderLayout.WEST);
		contentPane.add(version, BorderLayout.SOUTH);
		contentPane.add(createViewPanel(), BorderLayout.EAST);

		setLocation(100, 100);

		pack();

		colors = new LinkedHashMap<Class, Color>();
		setColor(Rabbit.class, Color.white);
		setColor(Fox.class, Color.orange);
		setColor(Bear.class, Color.magenta);
		setColor(Hunter.class, Color.blue);

		// Setup a valid starting point.
		sim.reset();

		setVisible(true);
	}

	private JPanel createSimuScherm() {
		fieldView = new FieldView(80, 80);
		stepLabel = new JLabel(STEP_PREFIX, JLabel.CENTER);
		population = new JLabel(POPULATION_PREFIX, JLabel.CENTER);

		JPanel simuscherm = new JPanel();
		simuscherm.setBorder(new EmptyBorder(6, 6, 6, 6));
		fieldView.setBorder(BorderFactory.createLineBorder(Color.black));
		simuscherm.setLayout(new BorderLayout());

		simuscherm.add(stepLabel, BorderLayout.NORTH);
		simuscherm.add(fieldView, BorderLayout.CENTER);
		simuscherm.add(population, BorderLayout.SOUTH);
		return simuscherm;
	}

	private JPanel createControllerPanel() {
		/**
		 * Here the panel with buttons is created.
		 */
		JPanel stappen = new JPanel();
		stappen.setBorder(new EmptyBorder(6, 6, 6, 6));
		stappen.setLayout(new GridLayout(5, 0));
		eenstap = new JButton("1 step");
		eenstap.addActionListener(this);
		honderdstap = new JButton("100 steps");
		honderdstap.addActionListener(this);
		vijfHstap = new JButton("500 steps");
		vijfHstap.addActionListener(this);
		reset = new JButton("reset");
		reset.addActionListener(this);
		stappen.add(eenstap);
		stappen.add(honderdstap);
		stappen.add(vijfHstap);
		stappen.add(reset);
		return stappen;
	}

	public JTabbedPane createViewPanel() {
		JTabbedPane tabbedPane = new JTabbedPane();

		JComponent panel1 = createHistoryPanel();
		tabbedPane.addTab("List", panel1);
		tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);
		
		JComponent panel2 = createCircleDiagram();
		tabbedPane.addTab("Cirkel", panel2); 
		tabbedPane.setMnemonicAt(0,KeyEvent.VK_2);
		
->		/*
		JComponent panel3 = "methode waar JComponent word gemaakt hier";
		tabbedPane.addTab("Histogram", panel3); 
		tabbedPane.setMnemonicAt(0,KeyEvent.VK_3);
		*/
		return tabbedPane;
	}

	public JComponent createCircleDiagram(){
		CircleDiagram circlediagram = new CircleDiagram();
		
		return circlediagram;
	}
	
	public JPanel createHistoryPanel() {
		JPanel history = new JPanel();
		history.setLayout(new BorderLayout());
		history.setBorder(new EmptyBorder(6, 6, 6, 6));
		hList = new JTextArea(100, 15);
		JScrollPane scrollPane = new JScrollPane(hList);
		hList.setEditable(false);
		hList.setBorder(BorderFactory.createLineBorder(Color.black));

		JLabel historyLabel = new JLabel("History (last 100 steps)");
		JTextArea columnTitles = new JTextArea();
		columnTitles.setEditable(false);
		columnTitles.append(setHNames(sim.getField()));
		JPanel hPanel = new JPanel();
		hPanel.setLayout(new GridLayout(2, 0));
		hPanel.add(historyLabel);
		hPanel.add(columnTitles);
		history.add(hPanel, BorderLayout.NORTH);
		history.add(scrollPane, BorderLayout.CENTER);

		return history;
	}

	public void makeMenuBar() {
		JMenuBar menubar = new JMenuBar();
		setJMenuBar(menubar);
		JMenu menu1 = new JMenu("Menu 1");
		JMenuItem item1 = new JMenuItem("menuItem1");
		menu1.add(item1);
		JMenu menu2 = new JMenu("Menu 2");
		JMenuItem item2 = new JMenuItem("menuItem2");
		menu2.add(item2);
		JMenu help = new JMenu("Help");
		JMenuItem menuHelp = new JMenuItem("help");
		help.add(menuHelp);
		menubar.add(menu1);
		menubar.add(menu2);
		menubar.add(help);
	}

	public void clearTextArea() {
		hList.setText("");
	}

	public String setHNames(Field field) {
		Field theField = field;
		String text = "";
		text += "Step | ";
		text += fieldstats.getNames(field);
		return text;
	}

	public void hText(Integer stepCount, Field field) {
		Field theField = field;
		String text = "";
		text += (stepCount + ": ");
		text += (fieldstats.getcounts(field));
		text += ("\n");
		hList.replaceRange(text, 0, 0);
		if (stepCount > 101) {
			hList.setText(verwijderRegel(hList.getText()));

		}
	}

	public static String verwijderRegel(String inhoud) {
		inhoud = inhoud.substring(0, inhoud.lastIndexOf('\n'));
		inhoud = inhoud.substring(0, inhoud.lastIndexOf('\n') + 1);
		return inhoud;
	}

	/**
	 * Show the current status of the field.
	 * 
	 * @param step
	 *            Which iteration step it is.
	 * @param field
	 *            The field whose status is to be displayed.
	 */

	public void showStatus(int step, Field field) {
		if (!isVisible()) {
			setVisible(true);
		}

		stepLabel.setText(STEP_PREFIX + step);
		fieldstats.reset();
		
		fieldView.preparePaint();

		for (int row = 0; row < field.getDepth(); row++) {
			for (int col = 0; col < field.getWidth(); col++) {
				Object animal = field.getObjectAt(row, col);
				if (animal != null) {
					fieldstats.incrementCount(animal.getClass());
					fieldView.drawMark(col, row, getColor(animal.getClass()));
				} else {
					fieldView.drawMark(col, row, EMPTY_COLOR);
				}
			}
		}
		fieldstats.countFinished();

		population.setText(POPULATION_PREFIX
				+ fieldstats.getPopulationDetails(field));
		fieldView.repaint();
	}
	
	/**
	 * Define a color to be used for a given class of animal.
	 * 
	 * @param animalClass
	 *            The animal's Class object.
	 * @param color
	 *            The color to be used for the given class.
	 */

	public void setColor(@SuppressWarnings("rawtypes") Class animalClass,
			Color color) {
		colors.put(animalClass, color);
	}

	/**
	 * @return The color to be used for a given class of animal.
	 */
	private Color getColor(@SuppressWarnings("rawtypes") Class animalClass) {
		Color col = colors.get(animalClass);
		if (col == null) {
			// no color defined for this class
			return UNKNOWN_COLOR;
		} else {
			return col;
		}
	}

	/**
	 * Determine whether the simulation should continue to run.
	 * 
	 * @return true If there is more than one species alive.
	 */
	public boolean isViable(Field field) {
		return fieldstats.isViable(field);
	}

	/**
	 * Provide a graphical view of a rectangular field. This is a nested class
	 * (a class defined inside a class) which defines a custom component for the
	 * user interface. This component displays the field. This is rather
	 * advanced GUI stuff - you can ignore this for your project if you like.
	 */
	private class FieldView extends JPanel {
		private final int GRID_VIEW_SCALING_FACTOR = 6;

		private int gridWidth, gridHeight;
		private int xScale, yScale;
		Dimension size;
		private Graphics g;
		private Image fieldImage;

		/**
		 * Create a new FieldView component.
		 */
		public FieldView(int height, int width) {
			gridHeight = height;
			gridWidth = width;
			size = new Dimension(0, 0);
		}

		/**
		 * Tell the GUI manager how big we would like to be.
		 */
		public Dimension getPreferredSize() {
			return new Dimension(gridWidth * GRID_VIEW_SCALING_FACTOR,
					gridHeight * GRID_VIEW_SCALING_FACTOR);
		}

		/**
		 * Prepare for a new round of painting. Since the component may be
		 * resized, compute the scaling factor again.
		 */
		public void preparePaint() {
			if (!size.equals(getSize())) { // if the size has changed...
				size = getSize();
				fieldImage = fieldView.createImage(size.width, size.height);
				g = fieldImage.getGraphics();

				xScale = size.width / gridWidth;
				if (xScale < 1) {
					xScale = GRID_VIEW_SCALING_FACTOR;
				}
				yScale = size.height / gridHeight;
				if (yScale < 1) {
					yScale = GRID_VIEW_SCALING_FACTOR;
				}
			}
		}

		/**
		 * Paint on grid location on this field in a given color.
		 */
		public void drawMark(int x, int y, Color color) {
			g.setColor(color);
			g.fillRect(x * xScale, y * yScale, xScale - 1, yScale - 1);
		}

		/**
		 * The field view component needs to be redisplayed. Copy the internal
		 * image to screen.
		 */
		public void paintComponent(Graphics g) {
			if (fieldImage != null) {
				Dimension currentSize = getSize();
				if (size.equals(currentSize)) {
					g.drawImage(fieldImage, 0, 0, null);
				} else {
					// Rescale the previous image.
					g.drawImage(fieldImage, 0, 0, currentSize.width,
							currentSize.height, null);
				}
			}
		}
	}

->	private class CircleDiagram extends JPanel { //CirkelDiagram klasse(werkt nog niet)
		private final int GRID_VIEW_SCALING_FACTOR = 6;

		private int gridWidth, gridHeight;
		private int xScale, yScale;
		Dimension size;
		private Graphics g;
		
		public CircleDiagram(){
			size = new Dimension(0, 0);
			this.setVisible(true);
		}
		
		public void paintComponent(Graphics g) { 
			g.setColor(Color.WHITE);
			g.fillRect(0, 0, 200, 200);
					
			int amountLeft = 360;
			int count = fieldstats.getTotalPop(sim.getField());
			ArrayList<Integer> aantallen = fieldstats.getAllCount();
			
			ArrayList<Integer> angles = new ArrayList<Integer>();
			for(int i = 0; i < aantallen.size(); i++){
				int perc = (360*(aantallen.get(i)/count));
				angles.add(perc);
			}
				g.setColor(Color.BLUE);
				g.fillArc(10, 10, 180, 180, 0, angles.get(0));
				g.setColor(Color.RED);
				g.fillArc(10, 10, 180, 180, angles.get(0), amountLeft-angles.get(1));
				g.setColor(Color.YELLOW);
				g.fillArc(10, 10, 180, 180, angles.get(1), amountLeft-angles.get(2));
				g.setColor(Color.GREEN);
				g.fillArc(10, 10, 180, 180, angles.get(2), amountLeft-angles.get(3));
		}
	}
	
}
